home *** CD-ROM | disk | FTP | other *** search
- /*
- * _ldiv - Division u / v
- *
- * Bestimme q und r mit u = q * v + r und 0 <= |r| < |v|.
- */
-
- long _ldiv (v,u)
- long u,v;
- {
- asm {
- movem.l D4-D7,-(A7)
- clr D7 ; kennzeichnet das Vorzeichen
- clr.l D0 ; Quotient q
- move.l u(A6),D5 ; u := (u1,u2)
- move.l v(A6),D3 ; v := (v1,v2)
- bne v_ok
- divs D3,D5 ; Division durch 0
- bra ret
- v_ok:
- bge v_ge
- neg.l D3
- addq #1,D7 ; negativer Quotient
- v_ge:
- tst.l D5
- bge u_ge
- neg.l D5
- addq #3,D7 ; negativer Dividend
- u_ge:
- cmp.l D5,D3
- bgt ready ; v > u ?
- bne not_eq ; v != u ?
- move.l #1,D0 ; q = 1
- clr.l D5 ; r = 0
- bra ready
- not_eq:
- move.l D3,D4
- swap D4
- tst D4
- beq v_word ; v < 2**16 ?
-
- moveq #15,D2 ; bestimme Normierungsfaktor
- move #0xFF00,D1
- and D4,D1
- beq len_8
- lsr #8,D4
- subq #8,D2
- len_8: moveq #0xF0,D1
- and.b D4,D1
- beq len_4
- lsr #4,D4
- subq #4,D2
- len_4: moveq #0xC,D1
- and.b D4,D1
- beq len_2
- lsr #2,D4
- subq #2,D2
- len_2: moveq #0x2,D1
- and.b D4,D1
- beq len_1
- subq #1,D2
- len_1:
- asl.l D2,D3 ; normalisiere v
- clr.l D4
- move D3,D4 ; D4 = v2
- clr D3
- swap D3 ; D3 = v1
-
- move.l D5,D6 ; normalisiere u
- clr D5
- swap D5
- asl.l D2,D5
- asl.l D2,D6 ; D6 = (u1,u2)
- move.l D6,D1
- swap D1
- move D1,D5 ; D5 = (u0,u1)
-
- divu D3,D5 ; (u0,u1) / v1
- move D5,D0 ; Quotient q
- move D6,D5 ; r * 2**16 + u2
- move D4,D1 ; v2
- mulu D0,D1 ; v2 * q
- q_test:
- cmp.l D1,D5
- bcc q_ok ; D5 >= D1 ? (32 Bit)
- subq #1,D0 ; q--
- sub.l D4,D1 ; unsigned
- add.l D3,D5 ; unsigned
- bcc q_test
- q_ok:
- sub.l D1,D5 ; Rest r
- lsr.l D2,D5
- bra ready
-
- v_word: ; Divisor hat nur 2 Byte
- move.l D5,D6
- clr D6
- swap D6 ; D6 = u1
- cmp D3,D6
- blt low_div
- divu D3,D6
- move D6,D0 ; Quotient : High-Word
- swap D0
- move D5,D6
- move.l D6,D5
- low_div:
- divu D3,D5
- move D5,D0 ; Quotient : Low-Word
- clr D5
- swap D5 ; Rest
-
- ready:
- cmp #3,D7
- blt r_pos
- neg.l D5 ; negiere Rest
- r_pos:
- lsr #1,D7
- bcc q_pos
- neg.l D0 ; negiere Quotient
- q_pos:
- move.l D0,v(A6)
- move.l D5,u(A6)
- ret:
- movem.l (A7)+,D4-D7
- }
- }